package HaplotypingOutputParser;
use IOutputParser;
use strict;
our @ISA = qw(IOutputParser); # inherits from IOutputParser

#constructor
sub new {
    my ($class) = @_;

    #call the constructor of the parent class, IOutputParser.
    my $self = $class->SUPER::new();
	$self->{_haplotypingLabels} = {};
	$self->{_haplotypingMaxLabel} = 0;
    bless $self, $class;
    return $self;
}

#inherited from IOutputParser
sub parseOutput{
	my ($self, $datWrapper, $pedWrapper, $outputFile, $currentMarkers, $currFamily) = @_;

	open HAPLOTYPING_RES, $outputFile;
	my @haplotypingData = <HAPLOTYPING_RES>;
	close HAPLOTYPING_RES;
	
	while ($#haplotypingData > -1) {
		#ignore all lines that doesn't have the format "<line_nuber> Allele_x_n_p_z = a"
		my @lineValues = split ' ', shift @haplotypingData;
		$#lineValues == 3 || next; 
		my @nameValues = split '_' , $lineValues[1];
		$nameValues[0] eq "Allele" || $nameValues[0] eq "Selector" || next;
		
		#read parameters from line
		my $locus = $nameValues[1];
		my $personNum = $nameValues[2];
		($currFamily eq $nameValues[3]) || next;
		my $strand = $nameValues[4];
		my $val = $lineValues[3];
		#save the information
		if ($nameValues[0] eq "Allele"){
			$self->{_haplotypingAllelesFromFile}{$personNum}{$locus+1}{$strand}=$val;
		}
		else{
			$self->{_haplotypingSelectorsFromFile}{$personNum}{$locus+1}{$strand}=$val;
		}		
	}
	
	#get all family members
	my @familyMembers = $pedWrapper->getFamilyMembers($currFamily);	
	for my $personNum (@familyMembers) {
		my $locus = 1;
		for my $markerNum (@{$currentMarkers}){
			my $label1 = $self->_getLabel($pedWrapper, $currFamily, $personNum, $locus, "0");
			my $label2 = $self->_getLabel($pedWrapper, $currFamily, $personNum, $locus, "1");			
			#save label cell
			my $cellOutputData = CellData->new();	
			$cellOutputData->val1($label1);
			$cellOutputData->val2($label2);
			$self->addLabelCell($cellOutputData, $personNum, $datWrapper->getMarkerName($markerNum));
			
			#save allele cell
			my $cellLabelData = CellData->new();	
			$cellLabelData->val1($self->{_haplotypingAllelesFromFile}{$personNum}{$locus}{"0"});
			$cellLabelData->val2($self->{_haplotypingAllelesFromFile}{$personNum}{$locus}{"1"});
			$self->addAlleleCell($cellLabelData, $personNum, $datWrapper->getMarkerName($markerNum));
			
			$locus = $locus + 1;
		}
	}
}

# get a label for a person, based on the haplotyping-output information
# Input: 	pedWrapper, family number, person nmber, marker number, 
# 			strand number ("0" for left label, "1" for right label)
sub _getLabel{
	my ($self, $pedWrapper, $personFamily, $personNum, $markerNum, $strand) = @_;
	#get the parent od this person
	my $parent =  $pedWrapper->getParent($personFamily, $personNum, $strand);
	
	#if person is founder- return arbitrary label
	if ($parent eq "0"){
		#if label was already defined- get it
		if (defined $self->{_haplotypingLabels}{$personNum}{$strand}){
			return $self->{_haplotypingLabels}{$personNum}{$strand};
		}
		#create new label for this founder
		$self->{_haplotypingMaxLabel} += 1;
		my $newLabel = $self->{_haplotypingMaxLabel};
		$self->{_haplotypingLabels}{$personNum}{$strand} = $newLabel;
		return $newLabel;
	}
	#else- person is not a founder. if label was already defined- get it
	if (defined $self->{_haplotypingLabels}{$personNum}{$markerNum}{$strand}){
		return $self->{_haplotypingLabels}{$personNum}{$markerNum}{$strand};
	}
	
	my $grandParent = $self->{_haplotypingSelectorsFromFile}{$personNum}{$markerNum}{$strand};
	if (not defined $grandParent){
		$grandParent = "0";
	}
	
	return $self->_getLabel($pedWrapper, $personFamily, $parent, $markerNum, $grandParent );
}

#inherited from IOutputParser
sub parseAlleles{
	my ($self, $allelsFile) = @_;
	#do nothing- all wad already done when reading output file
}
1;